<!DOCTYPE html>
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <title>Number of Aalto people users</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">
    <script type="text/javascript" src="js/vendor/jquery-1.8.2.min.js"></script>
    <script type="text/javascript" src="js/jQSparql.js"></script>
    <script type="text/javascript" src="js/d3.js"></script>
    <!-- CSS -->
    <!--<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet">-->
    <style type="text/css">

      /* Sticky footer styles
      -------------------------------------------------- */

      html,
      body {
        height: 100%;
        /* The html and body elements cannot have any padding or margin. */
      }

      /* Wrapper for page content to push down footer */
      #wrap {
        min-height: 100%;
        height: auto !important;
        height: 100%;
      }
      
      .container {
    width:100%;
    position:absolute;              
    min-height:100%; !important /* browser fill */
    height:auto;
	  }

#title {
   -webkit-text-stroke-width: 1px;
   -webkit-text-stroke-color: white;
	position: absolute;
    top: 10px;
    left: 20px;
	z-index:1;
	-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: default;
}

.link {
  stroke: #000;
  stroke-width: 1.5px;
}

.node {
  fill: #99CCFF;
  stroke: #000;
  stroke-width: 1px;
  cursor: none;
  user-select: none;
}

.selected {
    
}

.text {
  fill: #ffffff;
  stroke: #ffffff;
  pointer-events: none;
  font-family: sans-serif;
    cursor: none;
  user-select: none;
}

.dep {
 fill: #FC425A;   
}

.ARTS {
 fill: #FFA300;
}

.BIZ {
	fill: #75BA23;
}

.SCI {
	fill: #FF661A;
}

.CHEM {
	fill: #009577;
}

.ENG {
	fill: #C119A0;
}

.ELEC {
	fill: #7E69AA;
}

.A {
 fill: #0071C1;   
}

.ppl {
  fill: #FED40C;
}

.sup { 
   fill: #F6303D;
}

.tip {
  color:white;
  font-size: 18px;
  font-weight: bold;
  background-color:rgba(1,174,204,1);
  padding: 10px;
  border-radius: 8px;
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
  position: relative;
 font-family: sans-serif;
}

/* arrows - :before and :after */
.tip:before {
  position: absolute;
  display: inline-block;
  border-top: 5px solid transparent;
  border-right: 5px solid #eee;
  border-bottom: 5px solid transparent;
  border-right-color: rgba(1,174,204,1);
  left: -5px;
  content: '';
}
​

  </style>
  


<script type="text/javascript">//<![CDATA[ 
$(window).load(function(){
// Force directed

var endpoint = "http://data.aalto.fi/sparql";
var sparql = new jQSparql();
sparql.addPrefix("aiiso","http://purl.org/vocab/aiiso/schema#");
var prefix = sparql.prefix();
var posX;
var posY;

$("#svg").mousemove(function(event) {
  posX = event.pageX;
  posY = event.pageY;
});


var width = $("#svg").width(),
    height = $("#svg").height();
    

var color = d3.scale.category10();

var nodes = [],
    links = [];

 var tooltip = d3.select("#svg")
    .append("div")
    .attr("id","tooltip")
    .attr("class","tip")
    .style("position", "absolute")
    .style("visibility", "hidden");

var force = d3.layout.force()
    .friction(0.6)
    .gravity(0.1)
    .charge(-4000)
    .linkDistance(20)
    .linkStrength(0.5)
    .size([width, height])
    .on("tick", tick);

var svg = d3.select("#svg").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("pointer-events", "all")
  .append('g')
    .call(d3.behavior.zoom().on("zoom", redraw))
  .append('g');


var node, link;

svg.append('rect')
    .attr('width', width)
    .attr('height', height)
    .attr('fill', 'white');

function redraw() {
  svg.attr("transform",
      "translate(" + d3.event.translate + ")"
      + " scale(" + d3.event.scale + ")");

}

var mainNode = null;

sparql.query(endpoint, prefix+"SELECT (count(?person) as ?c) WHERE { ?person org:memberOf <http://data.aalto.fi/id/people/organization/AaltoUniversity> }").done(function(data) {
pplCount = parseInt(data.results.bindings[0].c.value);
mainNode = {id: "http://data.aalto.fi/id/people/organization/AaltoUniversity",name:"Aalto University",type:"A",size:pplCount,fixed:true,x:width/2,y:height/2,r:((Math.sqrt(pplCount/((height/width)*3)))*10)};
nodes.push(mainNode);
start();
});

function schoolType(s) {
	switch(s) {
		case "http://data.aalto.fi/id/people/organization/SchoolOfScience": return "SCI";
		case "http://data.aalto.fi/id/people/organization/SchoolOfEngineering": return "ENG";
		case "http://data.aalto.fi/id/people/organization/SchoolOfElectricalEngineering": return "ELEC";
		case "http://data.aalto.fi/id/people/organization/SchoolOfBusiness": return "BIZ";
		case "http://data.aalto.fi/id/people/organization/SchoolOfArtsDesignAndArchitecture": return "ARTS";
		case "http://data.aalto.fi/id/people/organization/SchoolOfChemicalTechnology": return "CHEM";
		case "http://data.aalto.fi/id/people/organization/Business": return undefined;
		case "http://data.aalto.fi/id/people/organization/Science": return undefined;
		default: return "dep";
	}
}

function onClick(d) {
    

    
    //var g = $.grep(nodes, function(e){ return e.id == id; });
    if(d.type != undefined) {
    if(d.type=="A") {
        d.r=10;
        sparql.query(endpoint, prefix+"SELECT DISTINCT ?s ?school (count(?member) as ?count) (count(?d) as ?dcount) WHERE { ?s rdfs:label ?school . ?s foaf:member ?member . ?s aiiso:part_of <"+d.id+"> FILTER(lang(?school)='en') OPTIONAL {?d aiiso:part_of ?s . }  } GROUP BY ?s ?school ?d").done(function(data) {
    
                      
    for(i in data.results.bindings) {
		if(data.results.bindings[i].s.value!="http://data.aalto.fi/id/people/organization/AaltoUniversity") {
        var rxy = randXY(d.x,d.y);
        var dtype = data.results.bindings[i].dcount.value === "0" ? d.id=="http://data.aalto.fi/id/people/organization/AaltoUniversity"?"sup":"ppl" : schoolType(data.results.bindings[i].s.value);
        var node = {id: data.results.bindings[i].s.value,name:data.results.bindings[i].school.value,type:dtype,size:data.results.bindings[i].count.value,x:rxy.x,y:rxy.y,r:((Math.sqrt(data.results.bindings[i].count.value/((height/width)*3)))*10)};
        
        nodes.push(node);
        links.push({source:mainNode,target:node}); }
   
    }
start();
});  
} else if(d.type!="ppl" && d.type!=undefined) {
    sparql.query(endpoint, prefix+"SELECT ?s ?school (count(?member) as ?count) WHERE { ?s rdfs:label ?school ; foaf:member ?member ; aiiso:part_of <"+d.id+"> FILTER(lang(?school)='en') } GROUP BY ?s ?school").done(function(data) {
    
    
    
    for(i in data.results.bindings) {
        var rxy = randXY(d.x,d.y);
        var node = {id: data.results.bindings[i].s.value,name:data.results.bindings[i].school.value,type:"ppl",size:data.results.bindings[i].count.value,x:rxy.x,y:rxy.y,r:((Math.sqrt(data.results.bindings[i].count.value/((height/width)*3)))*10)};
        nodes.push(node);
        links.push({source:d,target:node});
   
    }
start();
});  

}

d.text=d.type;
    d.type=null;
    
    } else {
        

        
    }
    

    
}

function randXY(x,y) {
 var rand = Math.random();
    var ag = rand * Math.PI * 2;
    var xl = x + Math.cos(ag) *50;
    var yl = y + Math.sin(ag) *50;  
    return {x:xl,y:yl};    
}

function start() {
    
        force
      .nodes(nodes)
      .links(links)
      .start();

      link = svg.selectAll("line").data(force.links(), function(d) { return d.source.id + "-" + d.target.id; });
  link.enter().insert("line",".node").attr("class", "link");
    
  link.exit().remove(); 
    
  node = svg.selectAll("g .node").data(force.nodes(), function(d) { return d.id;});
    
  var g = node.enter().append("g")
      .attr("class", "node")
      .call(force.drag)
      .on("click", function(d){
          var child = d3.selectAll(this.childNodes); 
        if(d.type!="ppl" && d.type!="sup" && d.type!=undefined) {	  
          onClick(d);
          d3.select(child[0][0]).transition().attr("r",30);
          d3.select(child[0][1])
      .text(""+d.text=="A"?"A?":d.text)
      .style("font-size", "20px") // initial guess
      .style("font-size", function(d) { return (2 * 35) / this.getComputedTextLength() * 10 + "px"; })
      .attr("text-anchor", "middle")
      .attr("dy", ".3em");
      }
      });
    
      
      var circle = g.append("circle")
      .attr("class", function(d) { return d.type; })
      .on("mouseover", function(d) { console.log(d); return d3.select("#tooltip").style("visibility", "visible").text(d.name);})
      .on("mousemove",function(d) { return tooltip.style("top", (posY-25)+"px").style("left",(posX+5)+"px"); })
      .on("mouseout",function(d) { return d3.select("#tooltip").style("visibility", "hidden"); })


circle.transition()
       .attr("r", function(d){ return d.r})

  g.append("text")
      .attr("class","text")
      .text(function(d) { return d.size })
      .style("font-size", function(d) { return (2 * d.r - 8) / this.getComputedTextLength() * 9 + "px"; })
      .attr("text-anchor", "middle")
      .attr("dy", ".3em");
  
    
  node.exit().remove();


   

}

function tick() {
  node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
  .each(collide(0.5));
  
  

  link.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });
}

// Resolves collisions between d and all other circles.
function collide(alpha) {
	var padding = 5;
  var quadtree = d3.geom.quadtree(nodes);
  return function(d) {
	
    var r = d.r + padding,
        nx1 = d.x - r,
        nx2 = d.x + r,
        ny1 = d.y - r,
        ny2 = d.y + r;
    quadtree.visit(function(quad, x1, y1, x2, y2) {
      
      if (quad.point && (quad.point !== d)) {
        var x = d.x - quad.point.x,
            y = d.y - quad.point.y,
            l = Math.sqrt(x * x + y * y),
            r = d.r + quad.point.r + padding;
        if (l < r) {
          l = (l - r) / l * alpha;
          d.x -= x *= l;
          d.y -= y *= l;
          quad.point.x += x;
          quad.point.y += y;
        }
      }
      return x1 > nx2
          || x2 < nx1
          || y1 > ny2
          || y2 < ny1;
    });
  };
}


});//]]>  



</script>
  
</head>
<body>
	<div id="wrapper">
      <div id="title"><h3>Number of users in Aalto People</h3></div>
      <div id="svg" class="container"></div>
   </div>
</body>
</html>
